import {createRouter, createWebHashHistory, RouteRecordRaw} from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {useAppStore} from '@/store/modules/app'
import {useUserStore} from '@/store/modules/user'
import {useRouterStore} from '@/store/modules/router'
import {i18n} from '@/i18n'
import {isExternalLink, pathToCamel} from '@/utils/tool'
import {useTabsStore} from '@/store/modules/tabs'
import {useMenuNavInButtApi} from "@/api/sys/menu";

NProgress.configure({showSpinner: false})

const constantRoutes: RouteRecordRaw[] = [
    {
        path: '/redirect',
        component: () => import('../layout/index.vue'),
        children: [
            {
                path: '/redirect/:path(.*)',
                component: () => import('../layout/components/Router/Redirect.vue')
            }
        ]
    },
    {
        path: '/iframe/:query?',
        component: () => import('../layout/components/Router/Iframe.vue')
    },
    {
        path: '/login',
        component: () => import('../views/login/index.vue')
    },
    {
        path: '/404',
        component: () => import('../views/404.vue')
    }

]

const asyncRoutes: RouteRecordRaw = {
    path: '/',
    component: () => import('../layout/index.vue'),
    redirect: '/home',
    children: [
        {
            path: '/home',
            name: 'Home',
            component: () => import('../views/home.vue'),
            meta: {
                title: i18n.global.t('router.home'),
                affix: true
            }
        },
        {
            path: '/profile/password',
            name: 'ProfilePassword',
            component: () => import('../views/profile/password.vue'),
            meta: {
                title: i18n.global.t('router.profilePassword'),
                cache: true
            }
        }
    ]
}

// 配置常量菜单
export const constantMenu = [
    {
        id: 1000,
        name: 'Demo',
        url: null,
        openStyle: 0,
        icon: 'icon-windows',
        children: [
            {
                id: 1001,
                name: 'Icon 图标',
                url: 'demo/icons/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1002,
                name: '表单设计器',
                url: 'demo/formDesign/form',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1003,
                name: '表单生成器',
                url: 'demo/formDesign/generate',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1004,
                name: '二维码生成',
                url: 'demo/qrcode/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1005,
                name: '页面打印',
                url: 'demo/printJs/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1006,
                name: '图片裁剪',
                url: 'demo/cropper/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1007,
                name: '富文本编辑器',
                url: 'demo/wangeditor/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1008,
                name: 'VForm3生成器',
                url: 'demo/formDesign/VForm3',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1008,
                name: 'VForm3渲染',
                url: 'demo/formDesign/VForm3-render',
                openStyle: 0,
                icon: 'icon-unorderedlist',
            },
            {
                id: 1008,
                name: 'Markdown',
                url: 'demo/markdown/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            },
            {
                id: 1009,
                name: 'ECharts图表',
                url: 'demo/echarts/index',
                openStyle: 0,
                icon: 'icon-unorderedlist'
            }
        ]
    }
]

export const errorRoute: RouteRecordRaw = {
    path: '/:pathMatch(.*)',
    redirect: '/404'
}

export const router = createRouter({
    history: createWebHashHistory(),
    routes: constantRoutes
})

// 白名单列表
const whiteList = ['/login']

// 路由跳转前
router.beforeEach(async (to, from, next) => {
    NProgress.start()

    const appStore = useAppStore()
    const userStore = useUserStore()
    const routerStore = useRouterStore()

    // token存在的情况
    if (userStore.token) {
        if (to.path === '/login') {
            next('/home')
        } else {
            // 用户信息不存在，则重新拉取
            if (!userStore.user.id) {
                try {
                    await userStore.getUserInfoAction()
                    await userStore.getAuthorityListAction()
                    await appStore.getDictListAction()
                } catch (error) {
                    // 请求异常，则跳转到登录页
                    userStore?.setToken('')
                    next('/login')
                    return Promise.reject(error)
                }

                // 动态菜单+常量菜单
                const menuRoutes = await routerStore.getMenuRoutes()

                //按钮路由
                const {data} = await useMenuNavInButtApi()
                const buttonRoutes = generateButtonRoutes(data)

                // 获取扁平化路由，将多级路由转换成一级路由
                const keepAliveRoutes = getKeepAliveRoutes(menuRoutes, [])

                keepAliveRoutes.push(...buttonRoutes)

                // 添加菜单路由
                asyncRoutes.children?.push(...keepAliveRoutes, )
                router.addRoute(asyncRoutes)

                // 错误路由
                router.addRoute(errorRoute)

                // 保存路由数据
                routerStore.setRoutes(constantRoutes.concat(asyncRoutes))

                // 搜索菜单需要使用
                routerStore.setSearchMenu(keepAliveRoutes)

                next({...to, replace: true})
            } else {
                next()
            }
        }
    } else {
        // 没有token的情况下，可以进入白名单
        if (whiteList.indexOf(to.path) > -1) {
            next()
        } else {
            next('/login')
        }
    }
})

// 路由加载后
router.afterEach((to, from) => {
    NProgress.done()
})

// 获取扁平化路由，将多级路由转换成一级路由
export const getKeepAliveRoutes = (rs: RouteRecordRaw[], breadcrumb: string[]): RouteRecordRaw[] => {
    const routerList: RouteRecordRaw[] = []

    rs.forEach((item: any) => {
        if (item.meta.title) {
            breadcrumb.push(item.meta.title)
        }

        if (item.children && item.children.length > 0) {
            routerList.push(...getKeepAliveRoutes(item.children, breadcrumb))
        } else {
            item.meta.breadcrumb.push(...breadcrumb)
            routerList.push(item)
        }

        breadcrumb.pop()
    })
    return routerList
}

// 加载vue组件
const layoutModules = import.meta.glob('/src/views/**/*.vue')

// 根据路径，动态获取vue组件
const getDynamicComponent = (path: string): any => {
    return layoutModules[`/src/views/${path}.vue`]
}

// 根据菜单列表，生成路由数据
export const generateRoutes = (menuList: any): RouteRecordRaw[] => {
    const routerList: RouteRecordRaw[] = []


    menuList.forEach((menu: any) => {

        let component
        let path
        if (menu.children && menu.children.length > 0) {
            component = () => import('@/layout/index.vue')
            path = '/p/' + menu.id
        } else {
            // 判断是否iframe
            if (isIframeUrl(menu)) {
                component = () => import('@/layout/components/Router/Iframe.vue')
                path = '/iframe/' + menu.id
            } else {
                component = getDynamicComponent(menu.url)
                path = '/' + menu.url
            }
        }

        const route: RouteRecordRaw = {
            path: path,
            name: pathToCamel(path),
            component: component,
            children: [],
            meta: {
                title: menu.name,
                icon: menu.icon,
                id: '' + menu.id,
                url: menu.url,
                cache: true,
                newOpen: menu.openStyle === 1,
                breadcrumb: []
            }
        }

        // 有子菜单的情况
        if (menu.children && menu.children.length > 0) {
            route.children?.push(...generateRoutes(menu.children))
        }
        routerList.push(route)
    })
    return routerList
}

// 根据按钮列表，生成路由数据
export const generateButtonRoutes = (buttonList: any): RouteRecordRaw[] => {
    const routerList: RouteRecordRaw[] = []
    buttonList.forEach((menu: any) => {
        const route: RouteRecordRaw = {
            path: '/' + menu.url,
            name: pathToCamel('/' + menu.url),
            component: getDynamicComponent(menu.url),
            children: [],
            meta: {
                title: menu.name,
                icon: menu.icon,
                id: '' + menu.id,
                url: menu.url,
                cache: true,
                newOpen: menu.openStyle === 1,
                breadcrumb: []
            }
        }
        routerList.push(route)
    })
    return routerList
}

// 判断是否iframe
const isIframeUrl = (menu: any): boolean => {
    // 如果是新页面打开，则不用iframe
    if (menu.openStyle === 1) {
        return false
    }

    // 是否外部链接
    return isExternalLink(menu.url)
}
